home *** CD-ROM | disk | FTP | other *** search
- #include "system.h"
- #include "indian.hpp"
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/shm.h>
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <unistd.h>
- #include <sys/fcntl.h>
- #include <fcntl.h>
-
-
- #include "netface.hpp"
- #include "nfserver.hpp"
- #include "view.hpp"
- #include "objects.hpp"
- #include "level.hpp"
- #include "timing.hpp"
- #include "server2.hpp"
- #include "game.hpp"
- #include "jwindow.hpp"
-
- extern char lsf[256];
-
- #define DIN_NAME "/tmp/.abuse_ndrv_out" // opposite of driver's in/out
- #define DOUT_NAME "/tmp/.abuse_ndrv_in"
-
- #define uchar unsigned char
- #define ushort unsigned short
-
- #define real2shm(type,ptr) (ptr==NULL ? NULL : ((type *)((char *)(ptr)-(char *)base)))
- #define shm2real(type,ptr) (ptr==NULL ? NULL : ((type *)((long)(ptr)+(long)(base))))
-
- #ifdef __sgi
- #define next_process() sginap(0)
- #else
- #define next_process() usleep(1)
- #endif
-
- extern int crc_man_write_crc_file(char *filename);
- int net_installed=0,net_out_fd,net_in_fd;
- int net_child=-1;
- int local_client_number=0;
-
- void *shm_addr=(void *)-1; // shmat returns -1 on failure
- base_memory_struct *base; // points to shm_addr
- base_memory_struct local_base;
-
- net_address *net_server=NULL;
-
- extern int registered;
-
- int net_start()
- {
- return net_server!=NULL;
- }
-
-
- int kill_net()
- {
-
- if (net_installed)
- {
- char cmd=EGCMD_DIE;
- write(net_out_fd,&cmd,1);
- read(net_in_fd,&cmd,1);
- close(net_out_fd);
- close(net_in_fd);
- }
-
- if (net_child!=-1)
- {
- kill(net_child,SIGINT);
- net_child=-1;
- }
-
- net_installed=0;
- if (shm_addr!=(void *)-1)
- {
- shmdt((char *)shm_addr);
- shm_addr=(void *)-1;
- base=&local_base;
- }
- }
-
- void net_uninit()
- {
- kill_net();
- }
-
- int net_init(int argc, char **argv)
- {
- int i,p1=-1,no_fork=0;
- base=&local_base;
- char *server_name=NULL;
-
- for (i=1;i<argc;i++)
- if (!strcmp(argv[i],"-nonet"))
- return 0;
- else if (!strcmp(argv[i],"-no_net_fork")) // make it easy to run the driver under a debugger
- no_fork=1;
- else if (!strcmp(argv[i],"-port"))
- {
- if (i==argc-1 || !sscanf(argv[i+1],"%d",&p1))
- {
- fprintf(stderr,"bad value folloing -port");
- return 0;
- }
- } else if (!strcmp(argv[i],"-net") && i<argc-1)
- {
- i++;
- server_name=argv[i];
- }
-
-
-
- char cmd[50];
- if (p1!=-1)
- sprintf(cmd,"undrv runme -port %d",p1);
- else sprintf(cmd,"undrv runme");
-
- if (!no_fork)
- {
- FILE *fp=popen(cmd,"rb");
- if (!fp || !fscanf(fp,"%d",&net_child) || net_child==-1)
- { fprintf(stderr,"could not run undrv, please make sure it's in your path\n");
- return 0;
- }
-
- if (fp) pclose(fp);
- }
-
- do
- { sleep(0);
- } while (access(DIN_NAME,R_OK));
- net_in_fd=open(DIN_NAME,O_RDWR);
-
- do
- { sleep(0);
- } while (access(DOUT_NAME,W_OK));
- net_out_fd=open(DOUT_NAME,O_RDWR);
-
-
- if (write(net_out_fd,®istered,sizeof(registered))!=sizeof(registered))
- return 0;
-
- int shm_seg_id;
- if (read(net_in_fd,&shm_seg_id,sizeof(shm_seg_id))!=sizeof(shm_seg_id))
- return 0;
-
- shm_addr=shmat(shm_seg_id,NULL,0); // attach as read/write
- if (shm_addr==(void *)-1)
- return 0;
-
- char ack=1; // acknodge we read and attached
- if (write(net_out_fd,&ack,1)!=1)
- return 0;
-
-
- base=(base_memory_struct *)shm_addr;
-
- net_installed=1;
-
- return 1;
- }
-
- #include <unistd.h>
- #include <sys/time.h>
-
- int NF_set_file_server(char *name)
- {
- if (net_installed)
- {
- char cm[2]={NFCMD_SET_FS,strlen(name)+1};
- if (write(net_out_fd,cm,2)!=2) { kill_net(); return 0; }
- if (write(net_out_fd,name,cm[1])!=cm[1]) { kill_net(); return 0; }
- if (read(net_in_fd,cm,1)!=1) { kill_net(); return 0; } // read the status of this command
- next_process();
- return cm[0];
- } else return 0;
- }
-
- int NF_open_file(char *filename, char *mode)
- {
- if (net_installed)
- {
- char cm[3]={NFCMD_OPEN,strlen(filename)+1,strlen(mode)+1};
- if (write(net_out_fd,cm,3)!=3) { kill_net(); return -1; }
- if (write(net_out_fd,filename,cm[1])!=cm[1]) { kill_net(); return -1; }
- if (write(net_out_fd,mode,cm[2])!=cm[2]) { kill_net(); return -1; }
-
- uchar file_type;
- if (read(net_in_fd,&file_type,1)!=1) { kill_net(); return -1; }
- if (file_type==NF_OPEN_LOCAL_FILE)
- {
- uchar name_size;
- if (read(net_in_fd,&name_size,1)!=1) { kill_net(); return -1; }
- int size=read(net_in_fd,filename,name_size);
- if (size!=name_size) { kill_net(); return -1; }
- return -2;
- }
- else if (file_type==NF_OPEN_FAILED) return -1;
-
- int fd;
- if (read(net_in_fd,&fd,sizeof(fd))!=sizeof(fd)) { kill_net(); return -1; }
-
- return fd;
- } else return -2; // return open local
- }
-
- long NF_close(int fd)
- {
- if (net_installed)
- {
- char cm=NFCMD_CLOSE;
- if (write(net_out_fd,&cm,1)!=1) { kill_net(); return 0; }
- if (write(net_out_fd,&fd,sizeof(fd))!=sizeof(fd)) { kill_net(); return 0; }
- char stat;
- if (read(net_in_fd,&stat,sizeof(stat))!=sizeof(stat)) { kill_net(); return 0; }
- return stat;
- } else return 0;
- }
-
-
- long NF_read(int fd, void *buf, long size)
- {
- if (net_installed && size)
- {
- char cm=NFCMD_READ;
-
- if (write(net_out_fd,&cm,1)!=1) { kill_net(); return 0; }
- if (write(net_out_fd,&fd,sizeof(fd))!=sizeof(fd)) { kill_net(); return 0; }
- if (write(net_out_fd,&size,sizeof(size))!=sizeof(size)) { kill_net(); return 0; }
-
- long total_read=0;
- ushort t=0xffff;
- while (size && t>=READ_PACKET_SIZE-2)
- {
- if (read(net_in_fd,&t,sizeof(t))!=sizeof(t)) { kill_net(); return 0; }
- if (read(net_in_fd,buf,t)!=t) { kill_net(); return total_read; }
-
- total_read+=t;
- size-=t;
- buf=(void *)((char *)buf+t);
-
-
- }
- return total_read;
- } else return 0;
- }
-
-
- long NF_filelength(int fd)
- {
- if (net_installed)
- {
- char cm=NFCMD_SIZE;
- if (write(net_out_fd,&cm,1)!=1) { kill_net(); return 0; }
- if (write(net_out_fd,&fd,sizeof(fd))!=sizeof(fd)) { kill_net(); return 0; }
- long size;
- if (read(net_in_fd,&size,sizeof(size))!=sizeof(size)) { kill_net(); return 0; }
- return size;
- } else return 0;
- }
-
- long NF_tell(int fd)
- {
- if (net_installed)
- {
- char cm=NFCMD_TELL;
- if (write(net_out_fd,&cm,1)!=1) { kill_net(); return 0; }
- if (write(net_out_fd,&fd,sizeof(fd))!=sizeof(fd)) { kill_net(); return 0; }
- long offset;
- if (read(net_in_fd,&offset,sizeof(offset))!=sizeof(offset)) { kill_net(); return 0; }
- return offset;
- } else return 0;
- }
-
- long NF_seek(int fd, long offset)
- {
- if (net_installed)
- {
- char cm=NFCMD_SEEK;
- if (write(net_out_fd,&cm,1)!=1) { kill_net(); return 0; }
- if (write(net_out_fd,&fd,sizeof(fd))!=sizeof(fd)) { kill_net(); return 0; }
- if (write(net_out_fd,&offset,sizeof(offset))!=sizeof(offset)) { kill_net(); return 0; }
-
- long offset;
- if (read(net_in_fd,&offset,sizeof(offset))!=sizeof(offset)) { kill_net(); return 0; }
- return offset;
- } else return 0;
- }
-
- static int aquire_mem_lock()
- {
- if (base->mem_lock==0 || base->mem_lock==2)
- {
- base->mem_lock=2;
- if (base->mem_lock==2)
- return 1;
- }
- // next_process(); // probably just gonna loop until we get the lock so halt for next preocess
- return 0;
- }
-
- void service_net_request()
- {
- if (net_installed)
- {
- if (base->input_state==INPUT_NET_DEAD)
- kill_net();
- else
- {
- if (aquire_mem_lock())
- {
- if (base->calc_crcs)
- {
- crc_man_write_crc_file(NET_CRC_FILENAME); // return 0 on failure
- base->calc_crcs=0;
- base->mem_lock=0;
-
- uchar cmd=NFCMD_CRCS_CALCED;
- if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return ; }
- } else base->mem_lock=0;
- }
- if (aquire_mem_lock())
- {
- if (base->get_lsf)
- {
- base->get_lsf=0;
- base->mem_lock=0;
- uchar c[2]={NFCMD_PROCESS_LSF,strlen(lsf)+1};
- if (write(net_out_fd,&c,2)!=2) { kill_net(); return ; }
- if (write(net_out_fd,lsf,c[1])!=c[1]) { kill_net(); return ; }
- } else base->mem_lock=0;
- }
- }
- }
- }
-
-
- int get_remote_lsf(char *name, char *filename) // filename should be 256 bytes
- {
- if (net_installed)
- {
- uchar cm[2]={NFCMD_REQUEST_LSF,strlen(name)+1};
- if (write(net_out_fd,cm,2)!=2) { kill_net(); return 0; }
- if (write(net_out_fd,name,cm[1])!=cm[1]) { kill_net(); return 0; }
- uchar size;
- if (read(net_in_fd,&size,1)!=1) { kill_net(); return 0; }
- if (size==0) return 0;
- if (read(net_in_fd,filename,size)!=size) { kill_net(); return 0; }
- return 1;
- } else return 0;
- }
-
- int request_server_entry()
- {
- if (net_installed)
- {
- if (!net_server) return 0;
- uchar cm[2]={NFCMD_REQUEST_ENTRY,strlen(net_server)+1};
- if (write(net_out_fd,cm,2)!=2) { kill_net(); return 0; }
- if (write(net_out_fd,net_server,cm[1])!=cm[1]) { kill_net(); return 0; }
- ushort cnum; // client number
- if (read(net_in_fd,&cnum,2)!=2) { kill_net(); return 0; }
- if (cnum==0) return 0;
- local_client_number=cnum;
- return 1;
- } else return 0;
- }
-
-
- int reload_start()
- {
- if (net_installed)
- {
- uchar cmd=NFCMD_RELOAD_START;
- if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return 0; }
- if (read(net_in_fd,&cmd,1)!=1) { kill_net(); return 0; }
- return cmd;
- } else return 1;
- }
-
-
- int reload_end()
- {
- if (net_installed)
- {
- uchar cmd=NFCMD_RELOAD_END;
- if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return 0; }
- if (read(net_in_fd,&cmd,1)!=1) { kill_net(); return 0; }
- return cmd;
- } else return 1;
- }
-
- void net_reload()
- {
- if (net_installed)
- {
- if (net_server)
- {
- if (current_level)
- delete current_level;
- bFILE *fp;
-
- if (!reload_start()) return ;
-
- do { // make sure server saves the file
- fp=open_file(NET_STARTFILE,"rb");
- if (fp->open_failure()) { delete fp; fp=NULL; }
- } while (!fp);
-
- spec_directory sd(fp);
-
- spec_entry *e=sd.find("Copyright 1995 Crack dot Com, All Rights reserved");
- if (!e)
- {
- the_game->show_help("This level is missing copyright information, cannot load\n");
- current_level=new level(100,100,"untitled");
- the_game->need_refresh();
- }
- else
- current_level=new level(&sd,fp,NET_STARTFILE);
-
- delete fp;
- base->current_tick=(current_level->tick_counter()&0xff);
-
- reload_end();
- } else if (current_level)
- {
-
- join_struct *join_list=shm2real(join_struct,base->join_list);
-
- while (!aquire_mem_lock())
- {
- next_process();
- service_net_request();
- }
-
- while (join_list)
- {
-
- view *f=player_list;
- for (;f && f->next;f=f->next); // find last player, add one for pn
- int i,st=0;
- for (i=0;i<total_objects;i++)
- if (!strcmp(object_names[i],"START"))
- st=i;
-
- game_object *o=create(current_start_type,0,0);
- game_object *start=current_level->get_random_start(320,NULL);
- if (start) { o->x=start->x; o->y=start->y; }
- else { o->x=100; o->y=100; }
-
- f->next=new view(o,NULL,shm2real(join_struct,base->join_list)->client_id);
- strcpy(f->next->name,shm2real(join_struct,base->join_list)->name);
- o->set_controller(f->next);
-
- if (start)
- current_level->add_object_after(o,start);
- else
- current_level->add_object(o);
-
- view *v=f->next;
-
- v->cx1=5;
- v->cy1=5;
- v->cx2=319-5;
- v->cy2=199-5;
- join_list=shm2real(join_struct,join_list->next);
- }
- base->join_list=NULL;
- current_level->save(NET_STARTFILE,1);
- base->mem_lock=0;
-
-
- jwindow *j=eh->new_window(0,yres/2,-1,-1,new info_field(WINDOW_FRAME_LEFT,
- WINDOW_FRAME_TOP,
- 0,"Clients are re-syncing, please wait...",NULL));
- eh->flush_screen();
- if (!reload_start()) return ;
-
- // wait for all client to reload the level with the new players
- do
- {
- next_process();
- } while (!reload_end());
- eh->close_window(j);
-
- }
- }
- }
-
- int client_number() { return local_client_number; }
-
-
- void send_local_request()
- {
- if (net_installed)
- {
- if (base->join_list)
- base->packet.write_byte(SCMD_RELOAD);
-
- uchar cmd=NFCMD_SEND_INPUT;
-
- if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return ; }
- if (read(net_in_fd,&cmd,1)!=1) { kill_net(); return ; }
- if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return ; }
- } else base->input_state=INPUT_PROCESSING;
- }
-
- void kill_slackers()
- {
- if (net_installed)
- {
- uchar cmd=NFCMD_KILL_SLACKERS;
- if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return ; }
- if (read(net_in_fd,&cmd,1)!=1) { kill_net(); return ; }
- }
- }
-
- int get_inputs_from_server(unsigned char *buf)
- {
- if (net_installed && base->input_state!=INPUT_PROCESSING) // if input is not here, wait on it
- {
- timeval start;
- gettimeofday(&start,NULL);
-
- int total_retry=0;
- jwindow *abort=NULL;
- linked_list input;
- while (base->input_state!=INPUT_PROCESSING)
- {
- if (!net_installed)
- {
- base->input_state=INPUT_PROCESSING;
- return 1;
- }
- server_check();
- service_net_request();
-
- timeval now; // if this is taking to long, the packet was probably lost, ask for it to be resent
- gettimeofday(&now,NULL);
- if ((((now.tv_sec-start.tv_sec)*100)+(now.tv_usec-start.tv_usec)/10000)>20)
- {
- // fprintf(stderr,"receive timeout %d\n",(((now.tv_sec-start.tv_sec)*100)+(now.tv_usec-start.tv_usec)/10000));
- uchar cmd=NFCMD_INPUT_MISSING;
- if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return 0; }
- if (read(net_in_fd,&cmd,1)!=1) { kill_net(); return 0; } // block, so net driver can request input
- gettimeofday(&start,NULL);
- total_retry++;
- if (total_retry==10) // 2 seconds and nothing
- {
- abort=eh->new_window(0,yres/2,-1,eh->font()->height()*4,
- new info_field(WINDOW_FRAME_LEFT,
- WINDOW_FRAME_TOP,
- 0,"Waiting for data...",
- new button(WINDOW_FRAME_LEFT,
- WINDOW_FRAME_TOP+eh->font()->height()+5,ID_NET_DISCONNECT,
- "Disconnect slackers",NULL)),"Error");
- eh->flush_screen();
- }
- }
- if (abort)
- {
- if (eh->event_waiting())
- {
- event ev;
- do
- {
- eh->get_event(ev);
- if (ev.type==EV_MESSAGE && ev.message.id==ID_NET_DISCONNECT)
- kill_slackers();
- else if (ev.type!=EV_MOUSE_MOVE) // no need to save mouse move events (likely to be a lot)
- {
- event *e=new event;
- *e=ev;
- input.add_front(e);
- }
- } while (eh->event_waiting());
-
- eh->flush_screen();
- }
- }
- }
-
- if (abort)
- {
- eh->close_window(abort);
- while (input.first()) // push all the key events
- {
- event *ev=(event *)input.first();
- input.unlink((linked_node *)ev);
- eh->push_event(ev);
- }
- }
- }
-
- // while (!aquire_mem_lock()) service_net_request();
-
- memcpy(base->last_packet.data,base->packet.data,base->packet.packet_size()+base->packet.packet_prefix_size());
-
- int size=base->packet.packet_size();
- memcpy(buf,base->packet.packet_data(),size);
-
- base->packet.packet_reset();
- base->mem_lock=0;
-
- return size;
- }
-
-
- void server_check() // read a byte from the net driver, causing the OS to give up the rest of our time-slice
- {
- if (net_installed)
- {
- if (base->input_state==INPUT_NET_DEAD)
- { close(net_out_fd); close(net_in_fd); net_installed=0; kill_net(); }
- else
- {
- uchar cmd=NFCMD_BLOCK;
- if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return ; }
- if (base->input_state==INPUT_NET_DEAD)
- { close(net_out_fd); close(net_in_fd); net_installed=0; kill_net(); }
- else
- {
- if (read(net_in_fd,&cmd,1)!=1) { kill_net(); return ; }
- if (base->input_state==INPUT_NET_DEAD)
- { close(net_out_fd); close(net_in_fd); net_installed=0; kill_net(); }
- else
- if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return ; }
- }
- }
- }
- }
-
- int become_server()
- {
- if (net_installed)
- {
- uchar cmd=NFCMD_BECOME_SERVER;
- if (write(net_out_fd,&cmd,1)!=1) { kill_net(); return 0; }
- if (read(net_in_fd,&cmd,1)!=1) { kill_net(); return 0; }
-
- return 1;
- }
- return 0;
- }
-
- void read_new_views() { ; }
-
-
-